﻿#pragma once
#include <windows.h>
#include <commctrl.h>
#include <vector>
#include <memory>
#include <functional>

extern "C" {
    // 示例：初始化控件
    void InitTableControl(HWND parent);
} 

#include "ITCatTableBase.h"
#include "ITCatTableRow.h"
#include "ITCatTableCell.h"
#include "ITCatTableColumn.h"
// 控件类名
#define ITCAT_TABLE_CONTROL_CLASS L"ITCatTableControl"

// 事件类型定义
enum TABLE_EVENT_TYPE {
    TABLE_EVENT_SELECTION_CHANGED = 1,  // 选中状态改变
    TABLE_EVENT_RIGHT_CLICK = 2,        // 右键点击
    TABLE_EVENT_EDIT_COMPLETED = 3,     // 编辑完成
    TABLE_EVENT_EDIT_CANCELLED = 4,     // 编辑取消
    TABLE_EVENT_HEADER_CLICK = 5,       // 列标题点击
    TABLE_EVENT_ROW_HEADER_CLICK = 6    // 行标题点击
};

// 事件数据结构
struct TABLE_EVENT_DATA {
    TABLE_EVENT_TYPE eventType;          // 事件类型
    int rowIndex;                        // 行索引 (-2: 行标题, -1: 无效区域)
    int colIndex;                        // 列索引 (-2: 列标题, -1: 无效区域)
    const wchar_t* oldText;              // 修改前的文本 (编辑事件) - 控件端负责释放
    const wchar_t* newText;              // 修改后的文本 (编辑事件) - 控件端负责释放
    POINT clickPoint;                    // 点击坐标 (右键事件)
    WPARAM wParam;                       // 额外参数
    LPARAM lParam;                       // 额外参数
};

// 事件回调函数类型
using TABLE_EVENT_CALLBACK = std::function<void(const TABLE_EVENT_DATA&)>;

// 自定义消息定义
#define WM_TABLE_EVENT (WM_USER + 100)

// 滚动信息结构体
struct TABLE_CONTROL_INFO {
    int scrollX = 0;      // 水平滚动位置
    int scrollY = 0;      // 垂直滚动位置
    int maxScrollX = 0;   // 最大水平滚动范围
    int maxScrollY = 0;   // 最大垂直滚动范围
};

// 列宽调整状态
struct COLUMN_RESIZE_INFO {
    bool isResizing = false;     // 是否正在调整列宽
    int resizeColumnIndex = -1;  // 正在调整的列索引
    int startX = 0;              // 开始调整时的X坐标
    int originalWidth = 0;       // 原始列宽
    int minWidth = 20;           // 最小列宽
    int maxWidth = 1000;         // 最大列宽
};

// 选中状态信息
struct SELECTION_INFO {
    std::vector<int> selectedRows;      // 选中的行索引
    std::vector<std::pair<int, int>> selectedCells;  // 选中的单元格索引 (行, 列)
    int focusedRow = -1;               // 当前焦点行
    int focusedCellRow = -1;           // 当前焦点单元格的行
    int focusedCellCol = -1;           // 当前焦点单元格的列
    bool isMultiSelect = false;        // 是否允许多选
    bool isFullRowSelect = false;      // 是否整行选择
};

// 编辑状态信息
struct EDIT_INFO {
    bool isEditing = false;            // 是否正在编辑
    int editRow = -1;                  // 正在编辑的行索引
    int editCol = -1;                  // 正在编辑的列索引
    HWND editControl = NULL;           // 编辑控件句柄
    std::wstring originalText;         // 原始文本内容
};

// 钩子管理信息
struct HOOK_INFO {
    HHOOK keyboardHook = NULL;         // 键盘钩子句柄
    bool hookInstalled = false;        // 钩子是否已安装
    HWND hookWindow = NULL;            // 钩子关联的窗口句柄
};

class ITCatTableControl:public ITCatTableBase{
public:
    ITCatTableControl();
    ~ITCatTableControl(); // 析构函数
    HWND m_hWnd;
    std::vector<std::unique_ptr<ITCatTableColumn>> columns;
    std::vector<std::unique_ptr<ITCatTableRow>> rows;
    TABLE_CONTROL_INFO m_Info;  // 滚动信息
    COLUMN_RESIZE_INFO m_ResizeInfo;  // 列宽调整信息
    SELECTION_INFO m_SelectionInfo;    // 选中状态信息
    EDIT_INFO m_EditInfo;              // 编辑状态信息
    HOOK_INFO m_HookInfo;              // 钩子管理信息

    // ImageList 相关
    HIMAGELIST m_hImageList;           // 图像列表句柄
    int m_iconSize;                    // 图标大小

    // 事件回调
    TABLE_EVENT_CALLBACK m_eventCallback;  // 事件回调函数

    ITCatTableColumn* AddColumn(const std::wstring& title, int width = 100);
    void AddRow(const std::wstring& rowTitle, const std::vector<std::wstring>& cellTexts);
    void SetRowHeight(size_t rowIndex, int height); // 设置指定行的高度
    void SetRowHeaderStyle(int style); // 设置行标题显示样式
    void SetRowHeaderVisible(bool visible); // 设置行标题显示/隐藏
    void SetRowAsSeparator(size_t rowIndex, bool isSeparator); // 设置指定行为分隔行
    void SetSeparatorAlignment(int alignment); // 设置分隔行对齐方式
    
    // 颜色设置方法
    void SetRowBackgroundColor(size_t rowIndex, COLORREF color); // 设置行的背景色
    void SetRowTextColor(size_t rowIndex, COLORREF color);       // 设置行的文本颜色
    void SetCellBackgroundColor(size_t rowIndex, size_t colIndex, COLORREF color); // 设置单元格的背景色
    void SetCellTextColor(size_t rowIndex, size_t colIndex, COLORREF color);       // 设置单元格的文本颜色
    
    // 选中相关方法
    void SelectRow(int rowIndex, bool addToSelection = false); // 选中指定行
    void SelectCell(int rowIndex, int colIndex, bool addToSelection = false); // 选中指定单元格
    void ClearSelection(); // 清除所有选中
    void SetMultiSelect(bool enable); // 设置是否允许多选
    void SetFullRowSelect(bool enable); // 设置是否整行选择
    bool IsRowSelected(int rowIndex); // 检查行是否被选中
    bool IsCellSelected(int rowIndex, int colIndex); // 检查单元格是否被选中
    int GetSelectedRowCount(); // 获取选中的行数
    int GetSelectedCellCount(); // 获取选中的单元格数
    const std::vector<int>& GetSelectedRows(); // 获取选中的行索引列表
    const std::vector<std::pair<int, int>>& GetSelectedCells(); // 获取选中的单元格索引列表
    
    // 辅助方法
    std::pair<int, int> GetRowColFromPoint(int x, int y); // 根据鼠标坐标计算点击的行和列
    
    // 编辑相关方法
    void StartEditing(int rowIndex, int colIndex); // 开始编辑指定单元格
    void StopEditing(bool commit = true); // 停止编辑，commit为true时提交更改
    bool IsEditing() const; // 检查是否正在编辑
    void HandleEditKeyDown(WPARAM wParam); // 处理编辑控件的按键事件
    bool PreTranslateMessage(MSG* pMsg); // 预处理消息，类似MFC的PreTranslateMessage
    void RepositionEditControl(); // 重新定位编辑框（滚动时调用）
    
    HWND CreateEditControl(int rowIndex, int colIndex, const RECT& cellRect); // 根据列类型创建编辑控件
    
    //控件窗口过程
    LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
    void UpdateScrollInfo(HWND hWnd);
    
    // 单元格合并相关方法
    void SetCellColspan(size_t rowIndex, size_t colIndex, int colspan); // 设置单元格的colspan
    void SetCellRowspan(size_t rowIndex, size_t colIndex, int rowspan); // 设置单元格的rowspan
    void SetCellSpan(size_t rowIndex, size_t colIndex, int colspan, int rowspan); // 同时设置colspan和rowspan
    bool IsCellVisible(size_t rowIndex, size_t colIndex); // 检查单元格是否应该被绘制（不是被合并的）
    RECT GetCellRect(size_t rowIndex, size_t colIndex); // 获取单元格的实际绘制矩形（考虑合并）

    // ImageList 相关方法
    void SetImageList(HIMAGELIST hImageList, int iconSize = 16);
    HIMAGELIST GetImageList() const;
    int GetIconSize() const;
    bool HasImageList() const;
    void DrawIcon(HDC hdc, int iconIndex, const RECT& rect);
    void DrawCheckBox(HDC hdc, const RECT& rect, bool checked, bool enabled = true);
    bool IsAllRowsSelected() const;
    void SelectAllRows(bool select);
    int GetCheckBoxHeaderWidth() const;

    // 事件相关方法
    void SetEventCallback(TABLE_EVENT_CALLBACK callback);
    void FireEvent(const TABLE_EVENT_DATA& eventData);
    void FireSelectionChangedEvent();
    void FireRightClickEvent(int rowIndex, int colIndex, const POINT& clickPoint);
    void FireEditCompletedEvent(int rowIndex, int colIndex, const std::wstring& oldText, const std::wstring& newText);
    void FireEditCancelledEvent(int rowIndex, int colIndex, const std::wstring& oldText);
    void FireHeaderClickEvent(int colIndex);
    void FireRowHeaderClickEvent(int rowIndex);

    // 钩子管理方法
    bool InstallKeyboardHook();         // 安装键盘钩子
    void UninstallKeyboardHook();       // 卸载键盘钩子
    static LRESULT CALLBACK KeyboardHookProc(int nCode, WPARAM wParam, LPARAM lParam); // 键盘钩子过程

public:
    // 静态方法 注册控件类
    static BOOL RegisterControlClass(HINSTANCE hInstance);
    static BOOL UnregisterControlClass(HINSTANCE hInstance);
    static HINSTANCE s_hInstance;
private:
    void OnDraw(HWND hWnd);
    // 滚动辅助方法
    int GetPreviousRowBoundary(int currentScrollY);
    int GetNextRowBoundary(int currentScrollY, int visibleHeight);
    int AlignScrollToRowBoundary(int scrollY);

};